#include <browserarea.h>

BrowserArea::BrowserArea(QWidget *parent) : QGraphicsView(parent)
{
    /* inicializa a página inicial */
    WebView* pagina = new WebView;
    pagina->load( getPaginaInicial() );
    paginaAtual = pagina;
    
    conectaSinaisPaginaAtual();
    
    /* adiciona a pagina inicial à cena e guarda o proxyWidget */
    QGraphicsProxyWidget* proxyItem = cena.addWidget( pagina );
    proxyItemAtual = proxyItem;

    /* adiciona a página e o proxyItem às suas listas */
    paginas << pagina;
    proxyItens << proxyItem;
    
    /* seta a cena para o view */
    setScene( &cena );
    
    itemPrincipal = new QGraphicsRectItem();
    cena.addItem( itemPrincipal );
    
    proxyItem->setParentItem( itemPrincipal );
    
    /* coloca uma imagem de fundo no view */
    setBackgroundBrush(QImage(":/images/fundo.png"));
    setCacheMode(QGraphicsView::CacheBackground);
    //setBackgroundBrush(QColor(Qt::gray));
    
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    
    tamanho = size();
    
    modoEscolhaAba = false;
}

QString BrowserArea::getPaginaInicial()
{
    QFile pConfFile("browserconf.txt");
    
    QString padrao("http://www.google.com");
    
    if ( QFile::exists( "browserconf.txt" ) )
        if ( pConfFile.open(QIODevice::ReadOnly | QIODevice::Text) )
            return pConfFile.readLine().trimmed();
        else
            return padrao;
    else
        return padrao;
}

void BrowserArea::newTab(const QUrl & url)
{
    paginaAtual->disconnect();
    
    proxyItemAnterior = proxyItemAtual;
    
    WebView* pagina = new WebView;
    
    if ( url.isValid() )
        pagina->load( url );
    else
        pagina->setContent( conteudoAbaVazia() );
    
    paginaAtual = pagina;
    
    QGraphicsProxyWidget* proxyItem = cena.addWidget( pagina );
    proxyItemAtual = proxyItem;
    
    proxyItem->setParentItem( itemPrincipal );
    
    /* adiciona a página e o proxyItem às suas listas */
    paginas << pagina;
    proxyItens << proxyItem;
    
    reposicionaPaginas();
    
    //como as posições foram todas recalculadas, move o itemPrincipal para o ítem anterior
    itemPrincipal->setPos( getPosItem(proxyItemAnterior) );
    
    //animação
    QTimeLine* timeLine = new QTimeLine;
    
    qreal dif_top;
    if (nrow == ncol) dif_top = 100 + (ncol-1)*5;
    else dif_top = (ncol-1)*5;
    
    QGraphicsItemAnimation *animacaoDiminuir = new QGraphicsItemAnimation;
    animacaoDiminuir->setItem(itemPrincipal);
    animacaoDiminuir->setTimeLine(timeLine);
    
    animacaoDiminuir->setScaleAt(0.3, 0.9/(ncol+1), 0.9/(ncol+1));
    animacaoDiminuir->setPosAt(0.3, posicaoExibirTodasAbas());
    
    animacaoDiminuir->setScaleAt(0.7, 0.9/(ncol+1), 0.9/(ncol+1));
    animacaoDiminuir->setPosAt(0.7, posicaoExibirTodasAbas());
    
    animacaoDiminuir->setScaleAt(1, 1, 1);
    animacaoDiminuir->setPosAt(1, getPosItem(proxyItemAtual));

    timeLine->setUpdateInterval(1000/25);
    timeLine->setDuration(3000);
    timeLine->start();

    mudouPagina();
}



void BrowserArea::reposicionaPaginas()
{
    int num_paginas = paginas.size();
    
    qreal result = sqrt(num_paginas);
    
    ncol = ceil(result);
    nrow = round(result);
    
    int row = 1, col = 1;
    for (int i=0; i<num_paginas; i++)
    {
        paginas.at(i)->setFixedSize( tamanho );
        
        if (i+1 > ncol*row)
        {
            row++;
            col = 1;
        }
        
        qreal wEspaco = width()/(ncol+1);
        proxyItens.at(i)->setPos( col*wEspaco + (col-1)*width(), row*wEspaco + (row-1)*height() );
        
        col++;
    }
}

/** Fecha aba corrente se houver duas ou mais abas abertas */
void BrowserArea::closeTab()
{
    if ( paginas.size() == 1) return;
    
    paginas.removeOne( paginaAtual );
    proxyItens.removeOne( proxyItemAtual );
    
    cena.removeItem( proxyItemAtual );
    paginaAtual->disconnect();
    
    reposicionaPaginas();
    
    proxyItemAtual = proxyItemAnterior;
    proxyItemAnterior = proxyItens.first();
    
    paginaAtual = paginas.at( proxyItens.indexOf(proxyItemAtual) );
    
    QTimeLine* timeLine = new QTimeLine;
    
    QGraphicsItemAnimation *animacaoDiminuir = new QGraphicsItemAnimation;
    animacaoDiminuir->setItem(itemPrincipal);
    animacaoDiminuir->setTimeLine(timeLine);
    
    animacaoDiminuir->setPosAt(1, getPosItem(proxyItemAtual));

    timeLine->setUpdateInterval(1000/25);
    timeLine->setDuration(1000);
    timeLine->start();
    
    mudouPagina();
}

void BrowserArea::chooseActivePage()
{
    //animação
    QTimeLine* timeLine = new QTimeLine;
    
    QGraphicsItemAnimation *animacaoDiminuir = new QGraphicsItemAnimation;
    animacaoDiminuir->setItem(itemPrincipal);
    animacaoDiminuir->setTimeLine(timeLine);
    
    animacaoDiminuir->setScaleAt(1, 0.9/(ncol+1), 0.9/(ncol+1));
    animacaoDiminuir->setPosAt(1, posicaoExibirTodasAbas());

    timeLine->setUpdateInterval(1000/25);
    timeLine->setDuration(1000);
    timeLine->start();
    
    modoEscolhaAba = true;
}

void BrowserArea::abaEscolhida(qreal x, qreal y)
{
    if (cena.itemAt( mapToScene(x,y)) == 0) return;
    
    proxyItemAnterior = proxyItemAtual;
    paginaAtual->disconnect();
    
    proxyItemAtual = (QGraphicsProxyWidget*) cena.itemAt( mapToScene(x,y) );
    
    paginaAtual = paginas.at( proxyItens.indexOf(proxyItemAtual) );
    
    QTimeLine* timeLine = new QTimeLine;
    
    QGraphicsItemAnimation *animacaoDiminuir = new QGraphicsItemAnimation;
    animacaoDiminuir->setItem(itemPrincipal);
    animacaoDiminuir->setTimeLine(timeLine);
    
    animacaoDiminuir->setScaleAt(0, 0.9/(ncol+1), 0.9/(ncol+1));
    animacaoDiminuir->setPosAt(0, posicaoExibirTodasAbas());
    
    animacaoDiminuir->setScaleAt(1, 1, 1);
    animacaoDiminuir->setPosAt(1, getPosItem(proxyItemAtual));

    timeLine->setUpdateInterval(1000/25);
    timeLine->setDuration(1000);
    timeLine->start();
    
    mudouPagina();
    
    modoEscolhaAba = false;
}

void BrowserArea::mousePressEvent(QMouseEvent* event)
{
    if (modoEscolhaAba)
    {
        abaEscolhida(event->x(), event->y());
        event->accept();
    }
    else
    {
        QGraphicsView::mousePressEvent(event);
	    event->ignore();
    }
}

QPoint BrowserArea::getPosItem( QGraphicsItem* item )
{
    return QPoint(
        -(item->pos().x() - mapToScene(0,0).x()),
        -(item->pos().y() - mapToScene(0,0).y())
    );
}

QPoint BrowserArea::posicaoExibirTodasAbas()
{
    return QPoint(mapToScene( 0,0 ).x() + 10, mapToScene( 0,0 ).y() );
}

/** Carrega url na aba corrente(ver QWebView) */
void BrowserArea::load(const QUrl & url)
{
    paginaAtual->load( url );
}

/** Recarrega aba corrente(ver QWebView) */
void BrowserArea::reload()
{
    paginaAtual->reload();
}

/** Interrompe carregamento da aba corrente(ver QWebView) */
void BrowserArea::stop()
{
    paginaAtual->stop();
}

/** Vai para proximo item no historico, se houver(ver QWebView) */
void BrowserArea::forward()
{
    paginaAtual->forward();
}

/** Volta um item no historico, se houver(ver QWebView) */
void BrowserArea::back()
{
    paginaAtual->back();
}

void BrowserArea::keyPressEvent(QKeyEvent* event)
{
    QGraphicsView::keyPressEvent(event);
    event->ignore();
}

void BrowserArea::wheelEvent(QWheelEvent* event)
{
    //QGraphicsView::wheelEvent(event);
    event->ignore();
}

void BrowserArea::novoTamanho()
{
    tamanho = this->size();
       
    reposicionaPaginas();
    
    //como mudou o tamanho, move para a pocição atual
    itemPrincipal->setPos( getPosItem(proxyItemAtual) );
}

QByteArray BrowserArea::conteudoAbaVazia()
{
    QFile arquivo("html/novaAba.html");
    arquivo.open(QIODevice::ReadOnly | QIODevice::Text);
    
    return arquivo.readAll();
}

void BrowserArea::mudouPagina()
{
    emit titleChanged( paginaAtual->title() );
    
    if ( paginaAtual->url().isValid()/* && paginaAtual->url() != QUrl("about:blank") */)
    {
        emit urlChanged( paginaAtual->url() );
        emit urlVisited( paginaAtual->url() );
    }
    
    conectaSinaisPaginaAtual();
}

void BrowserArea::statusMessagePaginaAtual ( const QString & text )
{
    emit statusBarMessage( text );
}

void BrowserArea::titleChangedPaginaAtual ( const QString & title )
{
    emit titleChanged( title );
}

void BrowserArea::urlChangedPaginaAtual ( const QUrl & url )
{
    emit urlChanged( url );
}

void BrowserArea::loadFinished ( bool ok )
{
    if (ok)
    {
        emit urlVisited( paginaAtual->url() );
    }
}

void BrowserArea::conectaSinaisPaginaAtual()
{
    connect(paginaAtual, SIGNAL(urlChanged(const QUrl&)), this, SLOT(urlChangedPaginaAtual(const QUrl&)));
    connect(paginaAtual, SIGNAL(titleChanged(const QString&)), this, SLOT(titleChangedPaginaAtual(const QString&)));
    connect(paginaAtual, SIGNAL(statusBarMessage(const QString&)), this, SLOT(statusMessagePaginaAtual(const QString&)));
    connect(paginaAtual, SIGNAL(loadFinished ( bool )), this, SLOT(loadFinished(bool)));
}
